<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>扫雷</title>
    <style>
    </style>
</head>
<style>
    *{
        margin: 0;
        padding:0;
    }
    div{
        float: left;
        width: 270px;
        margin: auto;
        margin-top: 20px;
    }
    ul{
        float: left;
    }
    ul li{
        width: 23px;
        height: 23px;
        list-style: none;
        text-decoration: none;
        background-color: lightgrey;
        border: 2px solid;
        border-color: #ffffff #a1a1a1 #a1a1a1 #ffffff;
        float: left;
        text-align: center;
        line-height: 25px;
        cursor:pointer;
    }
    .wrapper{
        width: 400px;
        text-align: center;
    }
    .demo{
        margin: auto;
    }
    button{
        width: 80px;
        height: 30px;
        font-size: 22px;
        font-weight: 700;
        background-color: lightskyblue;
        border: 2px solid #424242;
    }
    ol li{
    margin: 10px;
    }
    .boom{
        border:3px solid black;
    }
    </style>
    <body>
    <div class="wrapper">
    <button>初级</button>
    <button>中级</button>
    <button>高级</button>
    <br>
    <ol>
        <li>鼠标左键打开格子</li>
        <li>鼠标右键🚩</li>
        <li>方格内的数字表示周围存在的💣数量</li>
        <li>🚩全部💣为游戏胜利</li>
    </ol>
</div>
<div class="demo"></div>
<div class="boom">
</div>
</body>
</html>
<script>
    var ul = document.getElementsByTagName("ul");
    var btn = document.getElementsByTagName("button");
    var div = document.querySelector(".boom");
    var myBoom = document.querySelector(".demo");

    var boomNum = 15;
    var get = 0;
    var boom=[];
    var flag=[];
    var arr=[];

    btn[0].onclick=function(){
        div.remove();
        div=document.createElement("div");
        myBoom.appendChild(div);
        div.setAttribute("class","boom");
        createTable(10,10);
        setBoom(boomNum,10);
        setNumber(10,10);
        open(10);


    }
    btn[1].onclick=function(){
        div.remove();
        div=document.createElement("div");
        myBoom.appendChild(div);
        div.setAttribute("class","boom");
        div.style.width="433px";
        createTable(16,16);
        boomNum=40;
        setBoom(boomNum,16);
        setNumber(16,16);
        open(16);

    }
    btn[2].onclick=function(){
        div.remove();
        div=document.createElement("div");
        myBoom.appendChild(div);
        div.setAttribute("class","boom");
        div.style.width="540px";
        createTable(20,20);
        boomNum=80;
        setBoom(boomNum,20);
        setNumber(20,20);
        open(20);

    }
    document.oncontextmenu = function(e){
        //取消右键默认事件
        return false;
    }

    createTable(10,10);
    setBoom(boomNum,10);
    setNumber(10,10);
    open(10);

    function open(size){
        for(var i=0;i<ul.length;i++){
            (function(i){
                ul[i].onmousedown = function(e){
                    var j = [].indexOf.call(this.children,e.target);//这里获取到了具体的li的索引
                    // this.children ==> 十个li
                    // e.target     ==> 具体的li
                    if (e.button==2){
                        //右键插旗
                        e.preventDefault();
                        e.target.innerText = "🚩";
                        if (arr[i+1][j+1]=="💣"){
                            for (var k=0;k<flag.length;k++){
                                if(flag[k][0]==i+1 && flag[k][1]==j+1){
                                    flag.splice(k,1);
                                    get++;
                                    if (get==boomNum){
                                        alert("Victory!");
                                    }
                                }
                            }
                        }
                    }
                    else if(e.button==0){
                        //左键
                        if (arr[i+1][j+1]=="💣"){
                            //踩到雷了
                            alert("游戏结束😫😭");
                            get=-1000;
                            e.target.innerText = arr[i+1][j+1];
                            e.target.style.backgroundColor="#ff4184";
                            openAllBoom();
                        }
                        else if (arr[i+1][j+1]==0){
                            //打开格子为0
                            x=i+1;
                            y=j+1;
                            searchZero(x,y,size);
                        }
                        else{
                            //打开格子不为0
                            e.target.innerText = arr[i+1][j+1];
                        }
                    }
                }
            }(i))
        }
    }

    function searchZero(x,y,size){
        ul[x-1].children[y-1].innerText = "";//arr[x][y]
        var around=[];
        /*
        x-1,y-1     x-1,y   x-1,y+1
        x,y-1       x,y     x,y+1
        x+1,y-1     x+1,y   x+1,y+1
         */
        for(var i=x-1;i<=x+1;i++){
            for(var j=y-1;j<=y+1;j++){
                if( i<1 ||  //中心处于左边界
                    j<1 ||  //中心处于上边界
                    i>=size+1 ||  //中心处于右边界
                    j>=size+1 ||  //中心处于下边界
                    (i==x && j==y) ||   //循环到自己
                    arr[x][y] =="💣"//循环到的是雷
                ){
                    continue;
                }
                around.push([i,j]);//数据坐标
            }
        }
        console.log(around);

        for (var i=0;i<around.length;i++){
            var a=around[i][0];
            var b=around[i][1];
            ul[a-1].children[b-1].className=arr[a][b];
            ul[a-1].children[b-1].style.background="lightgrey";
            ul[a-1].children[b-1].style.border="2px solid lightgrey";
            if(arr[a][b]==0){
                if (ul[a-1].children[b-1].getAttribute("flag")!="flag"){
                    ul[a-1].children[b-1].setAttribute("flag","flag");
                    //遍历过的做标记
                    searchZero(a,b,size);
                }
            }
            else{
                ul[a-1].children[b-1].innerText=arr[a][b];
            }
        }

    }

    function setBoom(booNum,size){
        //size为网格尺寸
        for (var i = 1;i<=booNum;i++){
            //设置地雷
            var x = randomNum(size);
            var y = randomNum(size);
            if(arr[x][y]=="💣"){
                i--;
            }else{
                arr[x][y] = "💣";
                boom[i-1]=[x,y];
            }
        }
        flag = deepCopy(boom,flag);
    }

    function openAllBoom(){
        //点击到炸弹后打开全部炸弹
        for (var i=0;i<boom.length;i++){
            ul[boom[i][0]-1].children[boom[i][1]-1].innerText = arr[boom[i][0]][boom[i][1]];
        }
    }

    function setNumber(hen,shu){
        //为每个放个填上数字
        for (var i=1;i<=hen;i++){
            //设置小方格数值
            var num=0;
            for(var j=1;j<=shu;j++){
                if(arr[i][j]==0){
                    if (arr[i+1][j]=="💣") num++;
                    if (arr[i+1][j+1]=="💣") num++;
                    if (arr[i+1][j-1]=="💣") num++;
                    if (arr[i-1][j]=="💣") num++;
                    if (arr[i-1][j+1]=="💣") num++;
                    if (arr[i-1][j-1]=="💣") num++;
                    if (arr[i][j+1]=="💣") num++;
                    if (arr[i][j-1]=="💣") num++;
                    arr[i][j]=num;
                    num=0;
                }

            }
        }
    }

    function deepCopy(origin ,target){//深拷贝
        var target = target || {};//没有传target时就把target设为空
        toStr = Object.prototype.toString;//使用Object的toString用于判断对象还是数组
        arrStr = "[object Array]";//toString如果是数组的返回值
        for (var key in origin){
            if(origin.hasOwnProperty(key)){//排除原型链继承的属性
                if(origin[key] !== "null" && typeof(origin[key])=="object"){//引用类型的处理
                    if(toStr.call(origin[key])==arrStr){
                        target[key]=[];//如果是数组就初始化数组，进行递归
                    }else{
                        target[key]={};//如果是对象就初始化都对象，进行递归
                    }
                    deepCopy(origin[key],target[key]);//引用类型不能直接赋值，所以进行递归
                }else{//普通类型的处理
                    target[key]=origin[key];
                }
            }
        }
        return target;
    }

    function randomNum(x) {
        var num = parseInt(1+Math.random()*(x));
        return num;
    }

    function createTable(hang,lie){
        //hang和lie创建方格
        for (var i=0;i<hang;i++){
            var u=document.createElement("ul");
            for (var j=0;j<lie;j++){
                u.appendChild(document.createElement("li"));
            }
            div.appendChild(u);
        }
        for (var i=0;i<=hang+1;i++){
            arr[i]=[];
            for (var j=0;j<=lie+1;j++){
                arr[i].push(0);
            }
        }
    }
</script>
